package com.wuzheng.wisgo.sanitation.cloud.service.vehicleInfo.impl;

import com.wuzheng.wisgo.sanitation.cloud.enums.JobStatusEnum;
import com.wuzheng.wisgo.sanitation.cloud.model.tbox.pojo.ReceiveInfoSelectVehDto;
import com.wuzheng.wisgo.sanitation.cloud.model.vehicleInfo.EcharsShowDataSelectVehInfoDto;
import com.wuzheng.wisgo.sanitation.cloud.paraandgetutil.Exceptions;
import com.wuzheng.wisgo.sanitation.cloud.paraandgetutil.VehicleException;
import com.wuzheng.wisgo.sanitation.cloud.repository.entity.vehicle.BaVehicle;
import com.wuzheng.wisgo.sanitation.cloud.repository.mapper.vehicleInfo.VehInfoDataMapper;
import com.wuzheng.wisgo.sanitation.cloud.service.vehicleInfo.VehicleInfoService;
import com.wuzheng.wisgo.sanitation.framework.base.service.impl.BaseServiceImpl;
import com.wuzheng.wisgo.sanitation.framework.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/*
 * @MethodName: 车辆详情接口
 * @Description: TODO
 * @Author: sunpeng
 * @Date: 2019/12/4
 **/
@Service
public class VehicleInfoServiceImpl extends BaseServiceImpl<BaVehicle> implements VehicleInfoService {

    @Autowired
    private VehInfoDataMapper vehInfoDataMapper;

    /*
     * @MethodName: getVehInfoToBase
     * @Description: 车辆详情查询实现类
     * @Author: sunpeng
     * @Date: 2019/12/4
     **/
    @Override
    public BaVehicle getVehInfoToBase(String vehVin) throws VehicleException {
        if (StringUtils.isEmpty(vehVin)) {
            throw Exceptions.VehicleException("vin不能为空");
        }
        BaVehicle baVehicles = vehInfoDataMapper.selectByVehInfoToBase(vehVin);
        return baVehicles;
    }

    /*
     * @Description: 车辆总里程(每天)
     * @Author: sunpeng
     * @Date: 2019/12/6
    **/
    @Override
    public List<EcharsShowDataSelectVehInfoDto> getRecTotalMilesFromDay(String vehVin, String startTime, String stopTime) throws VehicleException {
        this.check(vehVin, startTime,stopTime);
        //JAVA默认的时区改为东八区
        System.setProperty("user.timezone", "Asia/Shanghai");
        TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
        TimeZone.setDefault(tz);
        if (StringUtils.isEmpty(startTime)) {
            logger.info("开始时间为空，默认查询时间为当前时间-30");
            startTime= String.valueOf(LocalDateTime.now().plusDays(-30).toInstant(ZoneOffset.of("+8")).toEpochMilli());
        }
        if (StringUtils.isEmpty(stopTime)) {
            logger.info("截止时间为空，默认查询时间为当前时间");
            stopTime= String.valueOf(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            startTime = sdf.format(new Date(Long.valueOf(startTime)));
            stopTime = sdf.format(new Date(Long.valueOf(stopTime)));
        } catch (Exception e) {
            e.printStackTrace();
            throw Exceptions.VehicleException("时间转换异常！");
        }

        List<EcharsShowDataSelectVehInfoDto> recTotalMilesFromDay = vehInfoDataMapper.getRecTotalMilesFromDay(vehVin, Timestamp.valueOf(startTime), Timestamp.valueOf(stopTime));
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startLocalTime = LocalDateTime.parse(startTime, df);
        LocalDateTime stopLocalTime = LocalDateTime.parse(stopTime, df);
        Duration duration = Duration.between(startLocalTime, stopLocalTime);
        //计算日期+1
        long days = duration.toDays()+1;
        List<EcharsShowDataSelectVehInfoDto> recTotalMiles=new ArrayList<>();
        if (days >= recTotalMilesFromDay.size()) {
            for (int i = 0; i < days; i++) {
                String strTime = startLocalTime.plusDays(i).format(DateTimeFormatter.ofPattern("MM/dd"));
                ArrayList<String> collect = recTotalMilesFromDay.stream().map(s -> s.getRecCollectionTime()).collect(Collectors.toCollection(ArrayList::new));
                boolean contains = collect.contains(strTime);
                if(!contains){
                    EcharsShowDataSelectVehInfoDto echarsShowDataSelectVehInfoDto=new EcharsShowDataSelectVehInfoDto();
                    echarsShowDataSelectVehInfoDto.setRecCollectionTime(strTime);
                    echarsShowDataSelectVehInfoDto.setRecCollectionTimeSort(startLocalTime.plusDays(i).format(DateTimeFormatter.ofPattern("yyyy/MM/dd")));
                    echarsShowDataSelectVehInfoDto.setRecTotalMiles(0D);
                    recTotalMiles.add(echarsShowDataSelectVehInfoDto);
                }
            }
        } else {
            throw Exceptions.VehicleException("数据处理异常，请检查查询时间！");
        }
        recTotalMiles.addAll(recTotalMilesFromDay);
        //根据日期排序
        arraySort(recTotalMiles);
        return recTotalMiles;
    }

    /*
     * @Description: 车辆作业总里程(每天)
     * @Author: sunpeng
     * @Date: 2019/12/6
     **/

    public List<EcharsShowDataSelectVehInfoDto> getWorkRecTotalMiles(String vehVin, String startTime, String stopTime) throws VehicleException {
        //先校验查询条件
        this.check(vehVin,startTime,stopTime);
        //JAVA默认的时区改为东八区
        System.setProperty("user.timezone", "Asia/Shanghai");
        TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
        TimeZone.setDefault(tz);

        if (StringUtils.isEmpty(startTime)) {
            logger.info("开始时间为空，默认查询时间为当前时间-30");
            startTime= String.valueOf(LocalDateTime.now().plusDays(-30).toInstant(ZoneOffset.of("+8")).toEpochMilli());
        }
        if (StringUtils.isEmpty(stopTime)) {
            logger.info("截止时间为空，默认查询时间为当前时间");
            stopTime= String.valueOf(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            startTime = sdf.format(new Date(Long.valueOf(startTime)));
            stopTime = sdf.format(new Date(Long.valueOf(stopTime)));
        } catch (Exception e) {
            e.printStackTrace();
            throw Exceptions.VehicleException("时间转换异常！");
        }

        //计算每天的总里程
        List<EcharsShowDataSelectVehInfoDto> recTotalMilesFromDay = vehInfoDataMapper.getRecTotalMilesFromDay(vehVin, Timestamp.valueOf(startTime), Timestamp.valueOf(stopTime));
        //查询当前时间下所有的数据
        List<ReceiveInfoSelectVehDto> workRecTotalMiles = vehInfoDataMapper.getWorkRecTotalMiles(vehVin, Timestamp.valueOf(startTime), Timestamp.valueOf(stopTime));
        if(workRecTotalMiles.size()>0){
            Double wokerTotalMiles = 0.0; //作业总里程
            Double notwokerTotalMiles = 0.0; //非作业总里程
            //根据时间分组并转换成map,以天为的单位分组
            Map<String, List<ReceiveInfoSelectVehDto>> collect = workRecTotalMiles.stream().collect(Collectors.groupingBy(ReceiveInfoSelectVehDto::getRecCollectionDaytime));
            //便利每天的数据map，计算非作业里程
            for(Map.Entry<String,List<ReceiveInfoSelectVehDto>> daylist:collect.entrySet()){
                String key=daylist.getKey();
                List<ReceiveInfoSelectVehDto> dayListValues=daylist.getValue();
                for (int i = 0; i < dayListValues.size(); i++) {
                    //计算工作里程
                    if (dayListValues.get(i).getRecJobStatus().equals(JobStatusEnum.STOPPING.getTypeId())) {
                        //非作业里程
                        Double wokerMiles=0D;
                        if(i+1==dayListValues.size()){
                            wokerMiles= dayListValues.get(i).getRecTotalMiles().doubleValue()-dayListValues.get(i-1).getRecTotalMiles().doubleValue();
                        }else {
                            wokerMiles= dayListValues.get(i+1).getRecTotalMiles().doubleValue()-dayListValues.get(i).getRecTotalMiles().doubleValue();
                        }
                        notwokerTotalMiles+=wokerMiles;
                    }
                }
                //此处理论上map.size==recTotalMilesFromDay.size
                if(collect.size()!=recTotalMilesFromDay.size()){
                    throw  Exceptions.VehicleException("工作历程数据与非工作里程数据不一致");
                }
                if(recTotalMilesFromDay.size()>0){
                    for(EcharsShowDataSelectVehInfoDto vehInfoDto:recTotalMilesFromDay){
                        if(vehInfoDto.getRecCollectionTime().equals(key)){
                            //工作里程=运行里程-非作业总里程;
                            wokerTotalMiles=vehInfoDto.getRecTotalMiles()-notwokerTotalMiles;
                            vehInfoDto.setWorkRecTotalMiles(wokerTotalMiles);
                        }
                    }
                }
            }
        }
        //计算日期+1
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime startLocalTime = LocalDateTime.parse(startTime, df);
        LocalDateTime stopLocalTime = LocalDateTime.parse(stopTime, df);
        Duration duration = Duration.between(startLocalTime, stopLocalTime);
        long days = duration.toDays()+1;
        //重组数据，并排序
        List<EcharsShowDataSelectVehInfoDto> recTotalMiles=new ArrayList<>();
        if (days >= recTotalMilesFromDay.size()) {
            for (int i = 0; i < days; i++) {
                String strTime = startLocalTime.plusDays(i).format(DateTimeFormatter.ofPattern("MM/dd"));
                ArrayList<String> collect = recTotalMilesFromDay.stream().map(s -> s.getRecCollectionTime()).collect(Collectors.toCollection(ArrayList::new));
                //当天如果没有数据默认为0
                boolean contains = collect.contains(strTime);
                if(!contains){
                    EcharsShowDataSelectVehInfoDto echarsShowDataSelectVehInfoDto=new EcharsShowDataSelectVehInfoDto();
                    echarsShowDataSelectVehInfoDto.setRecCollectionTime(strTime);
                    echarsShowDataSelectVehInfoDto.setWorkRecTotalMiles(0D);
                    echarsShowDataSelectVehInfoDto.setRecCollectionTimeSort(startLocalTime.plusDays(i).format(DateTimeFormatter.ofPattern("yyyy/MM/dd")));
                    recTotalMiles.add(echarsShowDataSelectVehInfoDto);
                }
            }
        } else {
            throw Exceptions.VehicleException("数据处理异常，请检查查询时间！");
        }
        recTotalMiles.addAll(recTotalMilesFromDay);
        //根据日期排序
        arraySort(recTotalMiles);
        return recTotalMiles;
    }

    /*
     * @Description: List<EcharsShowDataSelectVehInfoDto>集合根据时间排序
     * @Author: sunpeng
     * @Date: 2019/12/6
    **/
    public  List<EcharsShowDataSelectVehInfoDto> arraySort(List<EcharsShowDataSelectVehInfoDto> input){
        for (int i=0;i<input.size()-1;i++){
            for (int j=0;j<input.size()-i-1;j++) {
                if(input.get(j).getRecCollectionTimeSort().compareTo(input.get(j+1).getRecCollectionTimeSort())>0){
                    EcharsShowDataSelectVehInfoDto temp=input.get(j);
                    EcharsShowDataSelectVehInfoDto temp1=input.get(j+1);
                    input.remove(j);
                    input.add(j,temp1);
                    input.remove(j+1);
                    input.add(j+1,temp);
                }
            }
        }
        return input;
    }

    /*
     * @Description: 数据校验
     * @Author: sunpeng
     * @Date: 2019/12/6
    **/
    private void check(String vehVin, String startTime, String stopTime) throws VehicleException {
        if (StringUtils.isEmpty(vehVin)) {
            throw Exceptions.VehicleException("车牌号不能为空");
        }
        //此处理论上应该校验时间是否为空，但是考虑到前台校验后会存在为空的情况出现，就给添加默认值
    }

    /*
     * @Description: 油耗数据
     * @Author: sunpeng
     * @Date: 2019/12/6
     **/
    @Override
    public List<EcharsShowDataSelectVehInfoDto> getRecFuelQuantity(String vehVin, String startTime, String stopTime) throws VehicleException {
        this.check(vehVin, startTime,stopTime);
        if (StringUtils.isEmpty(startTime)) {
            logger.info("开始时间为空，默认查询时间为当前时间-30");
            startTime= String.valueOf(LocalDateTime.now().plusDays(-30).toInstant(ZoneOffset.of("+8")).toEpochMilli());
        }
        if (StringUtils.isEmpty(stopTime)) {
            logger.info("截止时间为空，默认查询时间为当前时间");
            stopTime= String.valueOf(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            startTime = sdf.format(new Date(Long.valueOf(startTime)));
            stopTime = sdf.format(new Date(Long.valueOf(stopTime)));
        } catch (Exception e) {
            e.printStackTrace();
            throw Exceptions.VehicleException("时间转换异常！");
        }
        List<EcharsShowDataSelectVehInfoDto> recFuelQuantity = vehInfoDataMapper.getRecFuelQuantity(vehVin, Timestamp.valueOf(startTime), Timestamp.valueOf(stopTime));
        return recFuelQuantity;
    }

//    public static void main(String[] orgs) {
//        String startTime = "1573488000000";
//        String stopTime = "1573833600000";
//        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        startTime=sdf.format(new Date(Long.valueOf(startTime)));
//        stopTime=sdf.format(new Date(Long.valueOf(stopTime)));
//        LocalDateTime startLocalTime = LocalDateTime.parse(startTime, df);
//        LocalDateTime stopLocalTime = LocalDateTime.parse(stopTime, df);
//        Duration duration = Duration.between(startLocalTime, stopLocalTime);
//        long days = duration.toDays();
//        String[] input=new String[] {"12/01","12/03","12/02","12/05","12/04"};
//        String[] keys=arraySort(input);
//        for (String key : keys) {
//            System.out.println(key);
//        }
//        Long s = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
//         LocalDateTime.now().plusDays(-30).toInstant(ZoneOffset.of("+8")).toEpochMilli();;
//
//        System.out.println(s);
//
//        System.setProperty("user.timezone", "Asia/Shanghai");
//        TimeZone tz = TimeZone.getTimeZone("Asia/Shanghai");
//        TimeZone.setDefault(tz);
//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        String times = format.format(new Date(Long.valueOf(startTime)));
//        System.out.print("日期格式---->" + times);
//
//    }

}
